package com.example.cloudindex.web;

import com.example.cloudindex.web.remote.IOrderAction;
import com.example.cloudindex.web.vo.Info;
import com.example.cloudindex.web.vo.Type;
import com.example.cloudindex.web.vo.User;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.yc.login.vo.LoginProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.lang.reflect.Proxy;
import java.util.Map;

@RestController
@RefreshScope //刷新范围
public class IndexAction {

    @Resource
    LoginProperties properties;

    @GetMapping("loginConfig")
    public LoginProperties loginConfig(){
        return properties;
    }

    @RequestMapping("index")
    public String index(HttpServletRequest request){
        return "index : "+ request.getServerPort();
    }

    @Resource
    RestTemplate restTemplate;
    @RequestMapping("order")
    @HystrixCommand(fallbackMethod = "hystrixOrder")
    public String order(){
        String url = "http://cloud-order/order";
        return restTemplate.getForObject(url, String.class);
    }

    public String hystrixOrder(){
        return "降级的 order";
    }

    @Resource
    IOrderAction orderAction;
    @RequestMapping("orderByFegin")
    public String orderByFegin(){
        return orderAction.order();
    }

    @RequestMapping("hello")
    public String hello(String name){
        return orderAction.hello(name);
    }

    @RequestMapping("add")
    public int add(int a, int b){
        return orderAction.add(a,b);
    }

    @RequestMapping("user")
    public User user(User user) {
        return orderAction.user(user);
    }

    @RequestMapping("user1")
    public User user1(User user, int newAge, char newGender) {
        return orderAction.user1(user, newAge, newGender);
    }

    @RequestMapping("hello/{name}")
    public String hello1(@PathVariable String name){
        return orderAction.hello1(name);
    }

    @RequestMapping("test")
    public Map<?,?> test(User user, Type type) {
        Info info = new Info();
        info.setUser(user);
        info.setType(type);
        return orderAction.test(info);
    }


//    Method has too many Body parameters:
//    public abstract int com.example.cloudindex.web.
//    remote.IOrderAction.add(int,int)

    public static void main(String[] args) {
        IOrderAction orderAction = proxy(IOrderAction.class);
        User user = new User();
        user.setName("abc");
        User user1 = orderAction.user(user);
        System.out.println("orderAction.order() = " + user1);
        System.out.println("user1.getName() = " + user1.getName());
        System.out.println("user1.getAge() = " + user1.getAge());
        System.out.println("user1.getGender() = " + user1.getGender());
    }

    public static <T> T proxy(Class<T> cls){
        return (T) Proxy.newProxyInstance(
                IOrderAction.class.getClassLoader(),
                new Class[]{cls},
                new InvocationHandler() {
                    RestTemplate restTemplate = new RestTemplate();
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        // 获取方法请求地址  例如: hello
                        String path = method.getAnnotation(RequestMapping.class).value()[0];
                        // 获取服务名
                        String serviceId = cls.getAnnotation(FeignClient.class).value();
                        // 将服务名转成 url => eureka 完成
                        serviceId = "127.0.0.1:8002";
                        String url = "http://"+ serviceId + "/" + path;
                        // 获取方法返回值类型
                        Class<?> returnType = method.getReturnType();
                        /**
                         * 如果是对象参数 => @RequestBody 标注 => json
                         * 如果是简单参数 => url 地址参数
                         * 扩展: 将访问中唯一标注 @RequestBody 的参数, 注入到 request
                         */
                        Object ret = restTemplate.postForObject(url, null, returnType);
                        return ret;
                    }
                });
    }

    @RequestMapping(value = "showCookie",
            produces = MediaType.TEXT_HTML_VALUE + ";charset=utf-8"
    )
    public String showCookie(String name, String value,
                             HttpServletRequest request,
                             HttpServletResponse response){
        String html = "<ol>";
        Cookie[] cookies = request.getCookies();
        if(cookies!=null){
            for (Cookie cookie : cookies) {
                html += "<li>" + cookie.getName() + " : " +
                        cookie.getValue() + "</li>";
            }
        }
        html += "</ol>";
        if(name!=null && value!=null){
            Cookie cookie = new Cookie(name,value);
            response.addCookie(cookie);
        }
        return html;
    }

    @GetMapping("setSession")
    public String setSession(String name, String value,
                             HttpSession session){
        session.setAttribute(name,value);
        return "保存数据到会话中!";
    }

    @GetMapping("getSession")
    public String getSession(String name,
                             HttpSession session){
        return "" + session.getAttribute(name);
    }

}
